Skip to content

Add MPFS250 QSPI support#677

Open
dgarske wants to merge 2 commits intowolfSSL:masterfrom
dgarske:polarfire_soc_qspi
Open

Add MPFS250 QSPI support#677
dgarske wants to merge 2 commits intowolfSSL:masterfrom
dgarske:polarfire_soc_qspi

Conversation

@dgarske
Copy link
Contributor

@dgarske dgarske commented Jan 29, 2026

Summary

  • Add MPFS250 QSPI support with two access paths: direct MSS QSPI controller and System Controller SPI services.
  • Introduce a QSPI-focused PolarFire config and extend the HAL/external-flash APIs for QSPI read/write/erase and SCB mailbox reads.
  • Tweak RISC-V build flow to select update loader based on disk usage and sign ELF outputs when ELF mode is enabled.
  • Add a PolarFire programming helper script and document QSPI usage under PolarFire targets.

Key Changes

  • New example config: config/examples/polarfire_mpfs250_qspi.config
  • QSPI init + drivers in hal/mpfs250.c (MSS QSPI + SC SPI paths)
  • Build logic updates in arch.mk for update loader selection + ELF signing
  • PolarFire QSPI documentation in docs/Targets.md
  • New tooling script: tools/scripts/mpfs_program.sh

Testing

  • Example output (with DEBUG_QSPI set):
wolfBoot Version: 2.7.0 (Jan 29 2026 13:03:10)
QSPI: Using System Controller SPI services
SC SPI: Read 0x20000 -> 0x80013680, len 512
SC SPI: Read 0x2000000 -> 0x80013680, len 512
Versions: Boot 1, Update 0
Trying Boot partition at 0x20000
Loading header 512 bytes from 0x20000 to 0x8DFFFE00
SC SPI: Read 0x20000 -> 0x8DFFFE00, len 512
Loading image 128664 bytes from 0x20200 to 0x8E000000...
SC SPI: Read 0x20200 -> 0x8E000000, len 128664
done
Boot partition: 0x8DFFFE00 (sz 128664, ver 0x1, type 0x601)
Checking integrity...done
Verifying signature...done
Successfully selected image in part: 0
Firmware Valid
SC SPI: Read 0x1FFFFFC -> 0x80013880, len 4
Loading elf at 0x8E000000
Found valid elf64 (little endian)
Program Headers 1 (size 56)
Load 21304 bytes (offset 0x1000) to 0x8E000000 (p 0x8E000000)
Clear 16392 bytes at 0x8E000000 (p 0x8E000000)
Entry point 0x8E0012B8
Booting at 0x8E0012B8
FDT: Invalid header! -1
QSPI: Using System Controller SPI services
========================
PolarFire SoC MPFS250 wolfBoot demo Application
Copyright 2025 wolfSSL Inc
GPL v3
========================

@dgarske dgarske self-assigned this Jan 29, 2026
@dgarske dgarske force-pushed the polarfire_soc_qspi branch 2 times, most recently from 633e7f8 to 5e963dc Compare January 30, 2026 22:19
@dgarske dgarske assigned danielinux and wolfSSL-Bot and unassigned dgarske Jan 30, 2026
@dgarske dgarske requested a review from danielinux January 30, 2026 22:19
Copy link
Member

@danielinux danielinux left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, some minor visibility issues

@dgarske dgarske force-pushed the polarfire_soc_qspi branch from 5e963dc to 2f8ce14 Compare February 4, 2026 00:20
@dgarske dgarske requested a review from danielinux February 4, 2026 00:22
@dgarske dgarske assigned danielinux and unassigned danielinux Feb 4, 2026
danielinux
danielinux previously approved these changes Feb 4, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds QSPI NOR flash support for PolarFire SoC MPFS250 and updates the RISC-V/PolarFire boot flow to better support RAM-loaded (NO_XIP) and ELF-based images.

Changes:

  • Introduces MPFS250 QSPI NOR driver + EXT_FLASH integration (including SC QSPI vs MSS QSPI selection).
  • Updates RISC-V trap/vector handling to switch between S-mode and M-mode via WOLFBOOT_RISCV_MMODE.
  • Adjusts build/link flow for RISC-V (update loader selection based on disk config; sign ELF when ELF=1) and documents PolarFire QSPI usage.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
hal/mpfs250.c Implements QSPI init + transfer/read/write/erase and hooks it into hal_init() when EXT_FLASH is enabled.
hal/mpfs250.h Adds SCB mailbox helpers/constants and CoreQSPI v2 register/flash command definitions under EXT_FLASH.
hal/riscv.h Centralizes privilege-mode selection helpers and adds an I-cache sync helper for RISC-V.
src/elf.c Uses memmove() for safer in-place ELF segment loading and syncs I-cache on RISC-V.
src/vector_riscv.S Switches S-mode/M-mode selection logic to WOLFBOOT_RISCV_MMODE.
src/boot_riscv_start.S Uses MODE_PREFIX from hal/riscv.h and updates mode checks to WOLFBOOT_RISCV_MMODE.
src/boot_riscv.c Updates satp/MMU teardown conditional for S-mode vs M-mode.
test-app/vector_riscv.S Adds RV64 trap entry/exit macros and uses sret vs mret based on WOLFBOOT_RISCV_MMODE.
test-app/startup_riscv.c Sets stvec vs mtvec and reads scause vs mcause based on privilege mode.
test-app/RISCV64-mpfs250.ld Adjusts placement for RAM boot / NO_XIP style execution and changes where .data/.bss live.
arch.mk Chooses update loader based on disk enablement and switches signing target to .elf when ELF=1.
docs/Targets.md Documents PolarFire QSPI usage and build-time selection between MSS QSPI and SC QSPI.
config/examples/polarfire_mpfs250_qspi.config New example configuration for MPFS250 QSPI + NO_XIP + ELF flows.
config/examples/polarfire_mpfs250.config Clarifies EXT_FLASH meaning for PolarFire MPFS250.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@danielinux danielinux assigned dgarske and unassigned danielinux and wolfSSL-Bot Feb 4, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


/* Verify erase (should be all 0xFF) */
memset(pageData, 0, sizeof(pageData));
ext_flash_read(TEST_EXT_ADDRESS, pageData, sizeof(pageData));
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return value of ext_flash_read is not checked here, but is checked on line 850. For consistency and robustness, the return value should be checked and handled in case the read operation fails during erase verification.

Suggested change
ext_flash_read(TEST_EXT_ADDRESS, pageData, sizeof(pageData));
ret = ext_flash_read(TEST_EXT_ADDRESS, pageData, sizeof(pageData));
if (ret < 0) {
wolfBoot_printf("Erase verify read failed: Ret %d\n", ret);
return ret;
}

Copilot uses AI. Check for mistakes.
remaining -= chunk_len;
}

return len;
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function qspi_flash_read returns len (uint32_t) on success (line 652), but its return type is int. If len exceeds INT_MAX (2147483647), the cast to int will produce a negative value that could be misinterpreted as an error code by callers. While this is unlikely in practice for flash operations, consider either: (1) changing the return type to match the convention (return int with length or negative error), or (2) adding a check to ensure len doesn't exceed INT_MAX before returning it.

Copilot uses AI. Check for mistakes.
- Both controllers share the same CoreQSPI v2 register interface.
The only difference is that SC QSPI does not need MSS clock/reset setup.

Example single-shot build: `cp config/examples/polarfire_mpfs250_qspi.config .config && make clean && make wolfboot.bin && hss-payload-generator -vvv -c ./hal/mpfs.yaml wolfboot.bin && make test-app/image.elf && ./tools/keytools/sign --ecc384 --sha384 test-app/image.elf wolfboot_signing_private_key.der 1`
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description mentions a new tooling script tools/scripts/mpfs_program.sh, but this file is not included in the PR changes and is not referenced in the documentation. If this script is intended to be part of this PR, it should be added. Otherwise, update the PR description to remove this reference.

Copilot uses AI. Check for mistakes.
@@ -62,6 +113,8 @@
mret
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 32-bit trap_exit macro has a hardcoded mret instruction but does not check the WOLFBOOT_RISCV_MMODE define. This is inconsistent with the 64-bit trap_exit macro (lines 65-69) which conditionally uses sret or mret based on privilege mode. If a 32-bit RISC-V system runs in supervisor mode, this will cause an illegal instruction exception. Add the same conditional logic as the 64-bit version.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants